home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 3
/
Aminet 3 - July 1994.iso
/
Aminet
/
dev
/
m2
/
Modules.lha
/
Modules
/
GraphicsSupport
/
GraphicsSupport.mod
/
GraphicsSupport.mod
Encoding:
Amiga (detected)
Atari
Commodore
DOS
FM Towns/JPY
Macintosh
Macintosh JP
Macintosh to JP
NeXTSTEP
RISC OS/Acorn
Shift JIS
UTF-8
Wrap
Modula Implementation
|
1993-12-22
|
55.5 KB
|
2,272 lines
IMPLEMENTATION MODULE GraphicsSupport;
(* Die Erklärung der Funktionen und Hinweise befinden sich im Definitionsfile *)
(* Compiler : M2Amiga 4.097d © 1991 by Andre Wiethoff *)
(*$ StackChk:=FALSE *)
(*$ RangeChk:=FALSE *)
(*$ OverflowChk:=FALSE *)
(*$ NilChk:=FALSE *)
(*$ CaseChk:=FALSE *)
(*$ ReturnChk:=FALSE *)
(*$ Volatile:=FALSE *)
(*$ StackParms:=FALSE *)
(*$ LargeVars:=FALSE *)
FROM SYSTEM IMPORT ADR,ADDRESS,BITSET,SHORTSET,CAST,REG,SETREG,
ASSEMBLE,LONGSET,FFP;
FROM FileSystem IMPORT File,WriteBytes,ReadBytes;
FROM GraphicsD IMPORT SimpleSprite,SimpleSpritePtr,BitMap,spriteAttached,
VSprite,VSpritePtr,Bob,BobPtr,VSpriteFlags,BitMapPtr,
VSpriteFlagSet,BobFlags,BobFlagSet,GelsInfo,AnimOb,
GelsInfoPtr,CollTable,GfxBasePtr,RastPortPtr,AnimComp,
ViewPortPtr,DBufPacket,View,ViewPort,ViewPtr,ViewModes,
RastPort,RasInfo,ColorMap,ViewModeSet,AnimObPtr,
AreaInfoPtr,RastPortFlags,RastPortFlagSet,AnimCompPtr,
ringtrigger,ColorMapFlagSet,DrawModes,DrawModeSet;
FROM GraphicsL IMPORT GetSprite,FreeSprite,MoveSprite,BltBitMap,SetRast,
ChangeSprite,AddVSprite,RemVSprite,AddBob,InitGels,
SortGList,DrawGList,InitMasks,DoCollision,SetRGB4,
SetCollision,RemIBob,LoadView,MrgCop,MakeVPort,
InitView,InitVPort,InitRastPort,InitBitMap,Text,
LoadRGB4,FreeVPortCopLists,FreeCprList,WaitTOF,
InitArea,AreaEnd,AreaMove,AreaDraw,InitTmpRas,
AreaEllipse,SetAPen,Move,Draw,AllocRaster,Flood,
FreeRaster,AddAnimOb,Animate,WaitBOVP,SetDrMd;
FROM GfxMacros IMPORT AreaCircle,SetOPen,RemBob;
FROM IntuitionL IMPORT RemakeDisplay;
FROM ExecL IMPORT TypeOfMem,CopyMem,FindTask;
FROM ExecD IMPORT MemReqSet,MemReqs,Task,TaskPtr;
FROM MathTrans IMPORT Sin,Cos;
FROM RememberHeap IMPORT NewAllocRemember,NewFreeRemember,NewRememberPtr,
CutRememberStructure,GetAddress;
FROM Hardware IMPORT custom,CollisionControlFlags,CollisionFlags,
CollisionControlFlagSet,CollisionFlagSet;
FROM String IMPORT Length;
IMPORT GraphicsL;
CONST notAdded = 0;
bobAdded = 1992;
TYPE NewBobPtr = POINTER TO RECORD
bob : Bob;
user : LONGINT;
END;
VAR rememberView : NewRememberPtr;
rememberBitmap : NewRememberPtr;
rememberData : NewRememberPtr;
gfxBase : GfxBasePtr;
PROCEDURE CopyToChip(data : ADDRESS;
count : LONGINT) : ADDRESS;
VAR adr : ADDRESS;
BEGIN
IF (data#NIL) AND (count#0) THEN
IF (NOT (chip IN TypeOfMem(data))) OR (count<0) THEN
count:=ABS(count);
adr:=NewAllocRemember(rememberData,count,TRUE);
IF adr#NIL THEN
CopyMem(data,adr,count);
END;
RETURN adr;
ELSE
RETURN data;
END;
END;
END CopyToChip;
PROCEDURE FreeChipData(VAR data : ADDRESS);
BEGIN
IF data#NIL THEN
CutRememberStructure(rememberData,data,TRUE);
data:=NIL;
END;
END FreeChipData;
PROCEDURE GetBitMap(width,height : INTEGER;
depth : INTEGER) : BitMapPtr;
VAR b : BitMapPtr;
err : BOOLEAN;
t : INTEGER;
BEGIN
b:=NIL;
b:=NewAllocRemember(rememberBitmap,SIZE(BitMap),FALSE);
IF b#NIL THEN
InitBitMap(b^,depth,width,height);
err:=FALSE;
FOR t:=0 TO depth-1 DO
b^.planes[t]:=NewAllocRemember(rememberData,
(((width-1) DIV 8)+1)*height,TRUE);
err:=err OR (b^.planes[t]=NIL);
END;
IF err THEN
FOR t:=0 TO 7 DO
IF b^.planes[t]#NIL THEN
CutRememberStructure(rememberData,b^.planes[t],TRUE);
END;
END;
CutRememberStructure(rememberBitmap,b,TRUE);
b:=NIL;
END;
END;
RETURN b;
END GetBitMap;
PROCEDURE FreeBitMap(VAR bitMap : BitMapPtr);
VAR t : INTEGER;
BEGIN
IF bitMap#NIL THEN
FOR t:=0 TO 7 DO
IF bitMap^.planes[t]#NIL THEN
CutRememberStructure(rememberData,bitMap^.planes[t],TRUE);
END;
END;
CutRememberStructure(rememberBitmap,bitMap,TRUE);
bitMap:=NIL;
END;
END FreeBitMap;
PROCEDURE GetRastPort(bitmap : BitMapPtr) : RastPortPtr;
VAR rp : RastPortPtr;
BEGIN
rp:=NewAllocRemember(rememberData,SIZE(RastPort),FALSE);
IF rp#NIL THEN
InitRastPort(rp^);
rp^.bitMap:=bitmap;
END;
RETURN rp;
END GetRastPort;
PROCEDURE FreeRastPort(VAR rp : RastPortPtr);
BEGIN
IF rp#NIL THEN
CutRememberStructure(rememberData,rp,TRUE);
rp:=NIL;
END;
END FreeRastPort;
PROCEDURE GetView(width,height : INTEGER;
depth : INTEGER;
modes : ViewModeSet;
colors : ADDRESS) : ViewHandlePtr;
VAR vh : ViewHandlePtr;
t : INTEGER;
err : BOOLEAN;
BEGIN
vh:=NewAllocRemember(rememberView,SIZE(ViewHandle),FALSE);
IF vh#NIL THEN
WITH vh^ DO
InitView(view);
InitVPort(viewPort);
InitRastPort(rastPort);
InitBitMap(bitMap,depth,width,height);
err:=FALSE;
FOR t:=0 TO depth-1 DO
bitMap.planes[t]:=NewAllocRemember(rememberData,
(((width-1) DIV 8)+1)*height,TRUE);
err:=err OR (bitMap.planes[t]=NIL);
END;
colorMap.colorTable:=NewAllocRemember(rememberData,64*2,TRUE);
err:=err OR (colorMap.colorTable=NIL);
IF NOT err THEN
view.viewPort:=ADR(viewPort);
view.modes:=modes;
viewPort.dWidth:=width;
viewPort.dHeight:=height;
viewPort.modes:=modes;
viewPort.rasInfo:=ADR(rasInfo);
viewPort.colorMap:=ADR(colorMap);
colorMap.flags:=ColorMapFlagSet{};
colorMap.type:=0;
colorMap.count:=64;
rasInfo.bitMap:=ADR(bitMap);
rasInfo.rxOffset:=0;
rasInfo.ryOffset:=0;
rasInfoDBPF.bitMap:=NIL;
rastPort.bitMap:=ADR(bitMap);
IF colors#NIL THEN
LoadRGB4(ADR(viewPort),colors,32);
END;
MakeVPort(ADR(view),ADR(viewPort));
MrgCop(ADR(view));
ELSE
IF colorMap.colorTable#NIL THEN
CutRememberStructure(rememberData,colorMap.colorTable,TRUE);
END;
FOR t:=0 TO 7 DO
IF bitMap.planes[t]#NIL THEN
CutRememberStructure(rememberData,bitMap.planes[t],TRUE);
END;
END;
CutRememberStructure(rememberView,vh,TRUE);
END;
END;
END;
RETURN vh;
END GetView;
PROCEDURE MakePlayfield(view : ViewHandlePtr;
bitmap : BitMapPtr);
BEGIN
IF (view#NIL) AND (bitmap#NIL) THEN
view^.rasInfoDBPF.bitMap:=bitmap;
view^.rasInfoDBPF.rxOffset:=0;
view^.rasInfoDBPF.ryOffset:=0;
view^.rasInfo.next:=ADR(view^.rasInfoDBPF);
END;
END MakePlayfield;
PROCEDURE SetPlayfieldPriority(view : ViewHandlePtr;
b : BOOLEAN);
BEGIN
IF view#NIL THEN
IF b THEN
INCL(view^.viewPort.modes,pfba);
INCL(view^.view.modes,pfba);
ELSE
EXCL(view^.viewPort.modes,pfba);
EXCL(view^.view.modes,pfba);
END;
END;
END SetPlayfieldPriority;
PROCEDURE SetViewPosition(view : ViewHandlePtr;
px,py : INTEGER);
BEGIN
IF view#NIL THEN
view^.view.dyOffset:=py;
view^.view.dxOffset:=px;
END;
END SetViewPosition;
PROCEDURE MoveView(view : ViewHandlePtr;
dx,dy : INTEGER);
BEGIN
IF view#NIL THEN
INC(view^.rasInfo.rxOffset,dx);
INC(view^.rasInfo.ryOffset,dy);
END;
END MoveView;
PROCEDURE MovePlayfield(view : ViewHandlePtr;
dx,dy : INTEGER);
BEGIN
IF view#NIL THEN
IF view^.rasInfoDBPF.bitMap#NIL THEN
INC(view^.rasInfoDBPF.rxOffset,dx);
INC(view^.rasInfoDBPF.ryOffset,dy);
END;
END;
END MovePlayfield;
PROCEDURE GetPlayfieldPos(vh : ViewHandlePtr;
VAR vx,vy : INTEGER;
VAR px,py : INTEGER);
BEGIN
IF vh#NIL THEN
vx:=vh^.rasInfo.rxOffset;
vy:=vh^.rasInfo.ryOffset;
px:=vh^.rasInfoDBPF.rxOffset;
py:=vh^.rasInfoDBPF.ryOffset;
END;
END GetPlayfieldPos;
PROCEDURE SetView(view : ViewHandlePtr);
BEGIN
IF view#NIL THEN
IF gfxBase^.actiView#ADR(view^.view) THEN
view^.oldView:=gfxBase^.actiView;
END;
MakeVPort(ADR(view^.view),ADR(view^.viewPort));
MrgCop(ADR(view^.view));
LoadView(ADR(view^.view));
END;
END SetView;
PROCEDURE FreeView(VAR view : ViewHandlePtr);
VAR rem : NewRememberPtr;
vh : ViewHandlePtr;
t : INTEGER;
BEGIN
IF view#NIL THEN
rem:=rememberView;
WHILE rem#NIL DO
vh:=GetAddress(rem);
IF (vh#view) AND (vh#NIL) THEN
IF vh^.oldView=ADR(view^.view) THEN
vh^.oldView:=view^.oldView;
END;
END;
rem:=rem^.next;
END;
IF view^.oldView#NIL THEN
LoadView(view^.oldView);
WaitTOF;
FreeVPortCopLists(ADR(view^.viewPort));
IF view^.view.lofCprList#NIL THEN
FreeCprList(view^.view.lofCprList);
END;
IF view^.view.shfCprList#NIL THEN
FreeCprList(view^.view.shfCprList);
END;
END;
IF view^.colorMap.colorTable#NIL THEN
CutRememberStructure(rememberData,view^.colorMap.colorTable,TRUE);
END;
FOR t:=0 TO 7 DO
IF view^.bitMap.planes[t]#NIL THEN
CutRememberStructure(rememberData,view^.bitMap.planes[t],TRUE);
END;
END;
CutRememberStructure(rememberView,view,TRUE);
view:=NIL;
END;
END FreeView;
VAR rememberRaster : NewRememberPtr;
PROCEDURE CreateTmpRas(rp : RastPortPtr) : RasterPtr;
VAR tr : RasterPtr;
hd : ADDRESS;
BEGIN
IF rp#NIL THEN
tr:=NewAllocRemember(rememberRaster,SIZE(Raster),FALSE);
IF tr#NIL THEN
WITH rp^.bitMap^ DO
hd:=AllocRaster(bytesPerRow*8,rows);
IF hd#NIL THEN
tr^.rp:=rp;
tr^.mem:=hd;
tr^.w:=bytesPerRow*8; tr^.h:=rows;
InitTmpRas(tr^.tmpRas,hd,bytesPerRow*rows);
tr^.former:=rp^.tmpRas;
rp^.tmpRas:=ADR(tr^.tmpRas);
ELSE
CutRememberStructure(rememberRaster,tr,TRUE);
tr:=NIL;
END;
END;
END;
END;
RETURN tr;
END CreateTmpRas;
PROCEDURE FreeTmpRas(VAR rast : RasterPtr);
VAR rem : NewRememberPtr;
rr : RasterPtr;
b : BOOLEAN;
BEGIN
IF rast#NIL THEN
WITH rast^ DO
IF mem#NIL THEN
FreeRaster(mem,w,h);
END;
END;
b:=TRUE;
rem:=rememberRaster;
WHILE rem#NIL DO
rr:=GetAddress(rem);
IF rr#rast THEN
IF rr^.former=ADR(rast^.tmpRas) THEN
rr^.former:=rast^.former;
b:=FALSE;
END;
END;
rem:=rem^.next;
END;
IF b THEN
rast^.rp^.tmpRas:=rast^.former;
END;
CutRememberStructure(rememberRaster,rast,TRUE);
rast:=NIL;
END;
END FreeTmpRas;
PROCEDURE GetPattern(pattern : ADDRESS;
nrbp : INTEGER;
wh : INTEGER) : ADDRESS;
VAR mem : ADDRESS;
c : POINTER TO ARRAY[0..7] OF SHORTSET;
d : POINTER TO SHORTSET;
t,x,y,i : INTEGER;
BEGIN
IF (pattern#NIL) AND (wh>0) AND (nrbp>0) AND (nrbp<=6) THEN
mem:=CopyToChip(pattern,(2*wh*nrbp));
IF mem#NIL THEN
d:=mem;
FOR t:=0 TO nrbp-1 DO
c:=pattern;
FOR y:=0 TO wh-1 DO
FOR x:=0 TO 1 DO
d^:=SHORTSET{};
FOR i:=0 TO 7 DO
IF t IN c^[i] THEN
INCL(d^,7-i);
END;
END;
INC(d);
INC(c,8);
END;
END;
END;
END;
END;
RETURN mem;
END GetPattern;
PROCEDURE FreePattern(VAR newpattern : ADDRESS);
BEGIN
FreeChipData(newpattern);
END FreePattern;
PROCEDURE SSetRGB4(vp : ViewPortPtr;
nr : CARDINAL;
col : CARDINAL);
BEGIN
IF vp#NIL THEN
SetRGB4(vp, nr, (col DIV 256) MOD 16, (col DIV 16) MOD 16, col MOD 16);
END;
END SSetRGB4;
PROCEDURE GetPos(rp : RastPortPtr;
VAR x,y : INTEGER);
BEGIN
IF rp#NIL THEN
x:=rp^.x; y:=rp^.y;
END;
END GetPos;
PROCEDURE WriteText(rp : RastPortPtr;
x,y : INTEGER;
col : INTEGER;
txt : ARRAY OF CHAR);
BEGIN
IF rp#NIL THEN
Move(rp,x,y);
SetAPen(rp,col);
Text(rp,ADR(txt),Length(txt));
END;
END WriteText;
PROCEDURE Line(rp : RastPortPtr;
x1,y1, x2,y2 : INTEGER;
col : INTEGER);
BEGIN
IF rp#NIL THEN
SetAPen(rp,col); Move(rp,x1,y1);
Draw(rp,x2,y2);
END;
END Line;
PROCEDURE Spline(rp : RastPortPtr;
x0,y0,x1,y1,x2,y2,x3,y3 : INTEGER;
s : INTEGER);
VAR x,y : ARRAY[0..3] OF ARRAY[0..3] OF FFP;
m : FFP;
c : INTEGER;
t,u : INTEGER;
ox,oy : INTEGER;
BEGIN
Move(rp,x0,y0);
x[0,0]:=FFP(x0);
x[1,0]:=FFP(x1);
x[2,0]:=FFP(x2);
x[3,0]:=FFP(x3);
y[0,0]:=FFP(y0);
y[1,0]:=FFP(y1);
y[2,0]:=FFP(y2);
y[3,0]:=FFP(y3);
c:=0;
FOR c:=1 TO s DO
m:=FFP(c)/FFP(s);
FOR t:=1 TO 3 DO
FOR u:=0 TO 3-t DO
x[u,t]:=x[u,t-1]+m*(x[u+1,t-1]-x[u,t-1]);
y[u,t]:=y[u,t-1]+m*(y[u+1,t-1]-y[u,t-1]);
END;
END;
ox:=TRUNC(x[0,3]);
oy:=TRUNC(y[0,3]);
Draw(rp,ox,oy);
END;
END Spline;
PROCEDURE Rect(rp : RastPortPtr;
x1,y1, x2,y2 : INTEGER;
col : INTEGER);
BEGIN
IF rp#NIL THEN
SetAPen(rp,col); Move(rp,x1,y1); Draw(rp,x1,y2);
Draw(rp,x2,y2); Draw(rp,x2,y1); Draw(rp,x1,y1);
END;
END Rect;
PROCEDURE InitSArea(rp : RastPortPtr;
max : INTEGER) : SAreaHandlePtr;
VAR ai : SAreaHandlePtr;
BEGIN
ai:=NewAllocRemember(rememberData,SIZE(SAreaHandle),FALSE);
IF ai#NIL THEN
ai^.rp:=rp;
ai^.mem:=NewAllocRemember(rememberData,(max+1)*5,FALSE);
IF ai^.mem#NIL THEN
ai^.max:=max;
InitArea(ai^.areaInfo,ai^.mem,max);
ai^.oAreaInfo:=rp^.areaInfo;
rp^.areaInfo:=ADR(ai^.areaInfo);
ELSE
CutRememberStructure(rememberData,ai,TRUE);
END;
END;
RETURN ai;
END InitSArea;
PROCEDURE SAreaMove(ai : SAreaHandlePtr;
x,y : INTEGER);
BEGIN
IF ai#NIL THEN
ai^.rp^.areaInfo:=ADR(ai^.areaInfo);
IF AreaMove(ai^.rp,x,y) THEN END;
END;
END SAreaMove;
PROCEDURE SAreaDraw(ai : SAreaHandlePtr;
x,y : INTEGER);
BEGIN
IF ai#NIL THEN
ai^.rp^.areaInfo:=ADR(ai^.areaInfo);
IF AreaDraw(ai^.rp,x,y) THEN END;
END;
END SAreaDraw;
PROCEDURE SAreaEllipse(ai : SAreaHandlePtr;
x,y : INTEGER;
a,b : INTEGER);
BEGIN
IF ai#NIL THEN
ai^.rp^.areaInfo:=ADR(ai^.areaInfo);
IF AreaEllipse(ai^.rp,x,y,a,b) THEN END;
END;
END SAreaEllipse;
PROCEDURE SAreaCircle(ai : SAreaHandlePtr;
x,y : INTEGER;
r : INTEGER);
BEGIN
IF ai#NIL THEN
ai^.rp^.areaInfo:=ADR(ai^.areaInfo);
IF AreaCircle(ai^.rp,x,y,r) THEN END;
END;
END SAreaCircle;
PROCEDURE SAreaEnd(VAR ai : SAreaHandlePtr;
type : SAreaEndFlag);
VAR tr : RasterPtr;
BEGIN
IF ai#NIL THEN
ai^.rp^.areaInfo:=ADR(ai^.areaInfo);
tr:=CreateTmpRas(ai^.rp);
IF tr#NIL THEN
IF type=aOutline THEN
INCL(ai^.rp^.flags,areaOutline);
ELSE
EXCL(ai^.rp^.flags,areaOutline);
END;
IF AreaEnd(ai^.rp) THEN END;
FreeTmpRas(tr);
ai^.rp^.areaInfo:=ai^.oAreaInfo;
END;
CutRememberStructure(rememberData,ai^.mem,TRUE);
CutRememberStructure(rememberData,ai,TRUE);
ai:=NIL;
END;
END SAreaEnd;
PROCEDURE Fill(rp : RastPortPtr;
fm : FillMode;
x,y : INTEGER;
oc : INTEGER);
VAR tr : RasterPtr;
BEGIN
IF rp#NIL THEN
tr:=CreateTmpRas(rp);
IF tr#NIL THEN
IF fm=fOutline THEN
SetOPen(rp,oc);
IF Flood(rp,0,x,y) THEN END;
ELSE
IF Flood(rp,1,x,y) THEN END;
END;
FreeTmpRas(tr);
END;
END;
END Fill;
VAR rememberSprite : NewRememberPtr;
PROCEDURE GetPair(a,b : SimpleSpritePtr;
nr : CARDINAL) : BOOLEAN;
VAR return : BOOLEAN;
BEGIN
return:=FALSE;
IF GetSprite(a,nr)#-1 THEN
IF GetSprite(b,nr-2*(nr MOD 2)+1)=-1 THEN
FreeSprite(nr);
ELSE
return:=TRUE;
END;
END;
RETURN return;
END GetPair;
PROCEDURE SnapSprite(nr : INTEGER;
rp : RastPortPtr;
x,y : CARDINAL;
h : CARDINAL;
dx,dy : CARDINAL;
attach : BOOLEAN) : SpriteHandlePtr;
PROCEDURE AllocData(VAR ss : SimpleSprite;
dx,dy : CARDINAL;
h : CARDINAL);
BEGIN
WITH ss DO
height:=h; x:=dx; y:=dy;
posctldata:=NewAllocRemember(rememberData,4*(h+2),TRUE);
END;
END AllocData;
VAR ss : SpriteHandlePtr;
bitmap : BitMap;
dca,dcb : POINTER TO ARRAY[0..255] OF CARDINAL;
zp : ADDRESS;
lc : LONGCARD;
BEGIN
ss:=NIL;
IF (h>0) AND (nr>=0) AND (nr<=7) THEN
ss:=NewAllocRemember(rememberSprite,SIZE(SpriteHandle),FALSE);
IF ss#NIL THEN
WITH ss^ DO
AllocData(sprite,dx,dy,h);
IF sprite.posctldata#NIL THEN
IF attach THEN
AllocData(attached,dx,dy,h);
is:=TRUE;
END;
IF (NOT attach) OR (attached.posctldata#NIL) THEN
dca:=sprite.posctldata;
dcb:=attached.posctldata;
IF (sprite.num>attached.num) AND attach THEN
zp:=dca; dca:=dcb; dcb:=zp;
END;
IF attach THEN
dca^[1]:=spriteAttached;
dcb^[1]:=spriteAttached;
END;
IF rp#NIL THEN
WITH bitmap DO
bytesPerRow:=4; rows:=h;
depth:=2; IF attach THEN depth:=4; END;
flags:=0;
planes[0]:=dca; INC(planes[0],4);
planes[1]:=dca; INC(planes[1],6);
IF attach THEN
planes[2]:=dcb; INC(planes[2],4);
planes[3]:=dcb; INC(planes[3],6);
END;
END;
lc:=BltBitMap(rp^.bitMap,x,y,ADR(bitmap),0,0,16,h,192,15,NIL);
END;
IF attach THEN
IF NOT GetPair(ADR(sprite),ADR(attached),nr) THEN
nr:=0;
WHILE (NOT GetPair(ADR(sprite),ADR(attached),nr)) AND (nr<8) DO
INC(nr,2);
END;
IF nr>7 THEN
sprite.num:=-1;
attached.num:=-1;
END;
END;
ELSE
IF GetSprite(ADR(sprite),nr)=-1 THEN
IF GetSprite(ADR(sprite),nr-2*(nr MOD 2)+1)=-1 THEN
sprite.num:=GetSprite(ADR(sprite),-1);
END;
END;
END;
ELSE
CutRememberStructure(rememberData,sprite.posctldata,TRUE);
CutRememberStructure(rememberSprite,ss,TRUE);
END;
ELSE
CutRememberStructure(rememberSprite,ss,TRUE);
END;
END;
END;
END;
RETURN ss;
END SnapSprite;
PROCEDURE EraseSprite(sh : SpriteHandlePtr);
BEGIN
IF sh#NIL THEN
WITH sh^ DO
IF sprite.num>=0 THEN
FreeSprite(sprite.num);
sprite.num:=-1;
END;
IF is THEN
IF attached.num>=0 THEN
FreeSprite(attached.num);
attached.num:=-1;
END;
END;
END;
END;
END EraseSprite;
PROCEDURE ResetSprite(sh : SpriteHandlePtr;
nr : INTEGER) : INTEGER;
BEGIN
IF sh#NIL THEN
WITH sh^ DO
IF is THEN
IF NOT GetPair(ADR(sprite),ADR(attached),nr) THEN
nr:=0;
WHILE (NOT GetPair(ADR(sprite),ADR(attached),nr)) AND (nr<8) DO
INC(nr,2);
END;
IF nr>7 THEN
sprite.num:=-1;
attached.num:=-1;
END;
END;
ELSE
IF GetSprite(ADR(sprite),nr)=-1 THEN
IF GetSprite(ADR(sprite),nr-2*(nr MOD 2)+1)=-1 THEN
sprite.num:=GetSprite(ADR(sprite),-1);
END;
END;
END;
END;
RETURN sh^.sprite.num;
ELSE
RETURN -2;
END;
END ResetSprite;
PROCEDURE RemSprite(VAR sh : SpriteHandlePtr);
BEGIN
IF sh#NIL THEN
EraseSprite(sh);
IF sh^.sprite.posctldata#NIL THEN
CutRememberStructure(rememberData,sh^.sprite.posctldata,TRUE);
END;
IF sh^.attached.posctldata#NIL THEN
CutRememberStructure(rememberData,sh^.attached.posctldata,TRUE);
END;
CutRememberStructure(rememberSprite,sh,TRUE);
sh:=NIL;
END;
END RemSprite;
PROCEDURE SaveSprite(VAR fh : File;
sh : SpriteHandlePtr);
VAR li : LONGINT;
BEGIN
IF (fh.file#NIL) AND (sh#NIL) THEN
WriteBytes(fh,sh,SIZE(SpriteHandle),li);
WITH sh^.sprite DO
IF posctldata#NIL THEN
WriteBytes(fh,posctldata,4*(height+2),li);
END;
END;
WITH sh^.attached DO
IF (posctldata#NIL) AND (sh^.is) THEN
WriteBytes(fh,posctldata,4*(height+2),li);
END;
END;
END;
END SaveSprite;
PROCEDURE LoadSprite(VAR fh : File;
nr : INTEGER;
dx,dy : CARDINAL) : SpriteHandlePtr;
VAR sh : SpriteHandlePtr;
li : LONGINT;
BEGIN
sh:=NIL;
IF (fh.file#NIL) THEN
sh:=NewAllocRemember(rememberSprite,SIZE(SpriteHandle),FALSE);
IF sh#NIL THEN
ReadBytes(fh,sh,SIZE(SpriteHandle),li);
WITH sh^ DO
IF sprite.posctldata#NIL THEN
WITH sprite DO
posctldata:=NewAllocRemember(rememberData,4*(height+2),TRUE);
IF posctldata#NIL THEN
ReadBytes(fh,posctldata,4*(height+2),li);
END;
END;
END;
IF (attached.posctldata#NIL) AND (sh^.is) THEN
WITH attached DO
posctldata:=NewAllocRemember(rememberData,4*(height+2),TRUE);
IF posctldata#NIL THEN
ReadBytes(fh,posctldata,4*(height+2),li);
END;
END;
END;
sprite.num:=-1;
attached.num:=-1;
sprite.x:=dx; sprite.y:=dy;
attached.x:=dx; attached.y:=dy;
IF ResetSprite(sh,nr)=0 THEN END;
END;
END;
END;
RETURN sh;
END LoadSprite;
PROCEDURE SetSpriteColors(sh : SpriteHandlePtr;
vp : ViewPortPtr;
c : ARRAY OF CARDINAL);
VAR nr,max,t : INTEGER;
BEGIN
IF (sh#NIL) AND (vp#NIL) THEN
nr:=sh^.sprite.num;
IF nr>=0 THEN
nr:=nr DIV 2;
nr:=nr*4+16;
max:=3;
IF sh^.is THEN
max:=15; nr:=16;
END;
FOR t:=0 TO max DO
IF t<=HIGH(c) THEN
SetRGB4(vp,nr+t,(c[t] DIV 256) MOD 16,
(c[t] DIV 16) MOD 16,c[t] MOD 16);
END;
END;
END;
END;
END SetSpriteColors;
VAR maxTest : INTEGER;
PROCEDURE SetSpriteCollision(planes : SHORTSET;
bits : SHORTSET;
sprites : SHORTSET;
maxTests : INTEGER);
VAR collision : CollisionControlFlagSet;
BEGIN
maxTest:=maxTests;
collision:=CollisionControlFlagSet{};
IF 0 IN planes THEN INCL(collision,enablePlane1); END;
IF 1 IN planes THEN INCL(collision,enablePlane2); END;
IF 2 IN planes THEN INCL(collision,enablePlane3); END;
IF 3 IN planes THEN INCL(collision,enablePlane4); END;
IF 4 IN planes THEN INCL(collision,enablePlane5); END;
IF 5 IN planes THEN INCL(collision,enablePlane6); END;
IF 0 IN bits THEN INCL(collision,plane1); END;
IF 1 IN bits THEN INCL(collision,plane2); END;
IF 2 IN bits THEN INCL(collision,plane3); END;
IF 3 IN bits THEN INCL(collision,plane4); END;
IF 4 IN bits THEN INCL(collision,plane5); END;
IF 5 IN bits THEN INCL(collision,plane6); END;
IF 1 IN sprites THEN INCL(collision,enableSprite01); END;
IF 3 IN sprites THEN INCL(collision,enableSprite23); END;
IF 5 IN sprites THEN INCL(collision,enableSprite45); END;
IF 7 IN sprites THEN INCL(collision,enableSprite67); END;
custom.clxcon:=collision;
END SetSpriteCollision;
PROCEDURE GetSpriteCollision(sh : SpriteHandlePtr) : SpriteCollisionSet;
VAR set : POINTER TO BITSET;
return : SpriteCollisionSet;
nr,t : INTEGER;
BEGIN
return:=SpriteCollisionSet{};
IF sh#NIL THEN
set:=ADR(custom.clxdat);
nr:=sh^.sprite.num;
nr:=((nr-(nr MOD 2)) DIV 2) MOD 4;
FOR t:=0 TO maxTest DO
IF (nr+1) IN set^ THEN
INCL(return,oddPlane);
END;
IF (nr+5) IN set^ THEN
INCL(return,evenPlane);
END;
CASE nr OF
|0 : IF 9 IN set^ THEN INCL(return,sprite2or3); END;
IF 10 IN set^ THEN INCL(return,sprite4or5); END;
IF 11 IN set^ THEN INCL(return,sprite6or7); END;
|1 : IF 12 IN set^ THEN INCL(return,sprite4or5); END;
IF 13 IN set^ THEN INCL(return,sprite6or7); END;
|2 : IF 14 IN set^ THEN INCL(return,sprite6or7); END;
ELSE
END;
END;
END;
RETURN return;
END GetSpriteCollision;
PROCEDURE NewSpriteGraphics(sh : SpriteHandlePtr;
vp : ViewPortPtr;
data : ADDRESS);
BEGIN
IF (sh#NIL) AND (vp#NIL) AND (data#NIL) THEN
WITH sh^ DO
ChangeSprite(vp,ADR(sprite),data);
IF is THEN
INC(data,sprite.height*4);
ChangeSprite(vp,ADR(attached),data);
END;
END;
END;
END NewSpriteGraphics;
PROCEDURE MoveSpriteTo(sh : SpriteHandlePtr;
vp : ViewPortPtr;
x,y : INTEGER);
BEGIN
IF (sh#NIL) AND (vp#NIL) THEN
WITH sh^ DO
MoveSprite(vp,ADR(sprite),x,y);
IF is THEN
MoveSprite(vp,ADR(attached),x,y);
END;
END;
END;
END MoveSpriteTo;
VAR rememberVSprite : NewRememberPtr;
PROCEDURE MoveVSprite(vsp : VSpritePtr;
x,y : INTEGER);
BEGIN
IF vsp#NIL THEN
vsp^.x:=x;
vsp^.y:=y;
END;
END MoveVSprite;
PROCEDURE MoveBob(bob : BobPtr;
x,y : INTEGER);
BEGIN
IF bob#NIL THEN
MoveVSprite(bob^.bobVSprite,x,y);
END;
END MoveBob;
PROCEDURE RedrawGels(rp : RastPortPtr;
vp : ViewPortPtr;
view : ViewPtr;
wait : RedrawWaitMode);
BEGIN
IF (rp#NIL) AND (vp#NIL) THEN
SortGList(rp);
DrawGList(rp,vp);
IF view#NIL THEN
MakeVPort(view,vp);
MrgCop(view);
IF wait=waitTOF THEN WaitTOF;
ELSIF (wait=waitBOVP) AND (vp#NIL) THEN WaitBOVP(vp);
END;
LoadView(view);
ELSE
IF wait=waitTOF THEN WaitTOF;
ELSIF (wait=waitBOVP) AND (vp#NIL) THEN WaitBOVP(vp);
END;
RemakeDisplay;
END;
END;
END RedrawGels;
PROCEDURE DeallocateGel(vsp : VSpritePtr);
BEGIN
IF vsp#NIL THEN
WITH vsp^ DO
IF vsBob#NIL THEN
IF vsBob^.dBuffer#NIL THEN
CutRememberStructure(rememberData,vsBob^.dBuffer^.bufBuffer,TRUE);
CutRememberStructure(rememberData,vsBob^.dBuffer,TRUE);
END;
CutRememberStructure(rememberData,vsBob^.saveBuffer,TRUE);
CutRememberStructure(rememberData,vsBob,TRUE);
END;
CutRememberStructure(rememberData,imageData,TRUE);
CutRememberStructure(rememberData,collMask,TRUE);
CutRememberStructure(rememberData,borderLine,TRUE);
END;
CutRememberStructure(rememberVSprite,vsp,TRUE);
END;
END DeallocateGel;
PROCEDURE SaveVSprite(VAR fh : File;
vsp : VSpritePtr);
VAR li : LONGINT;
BEGIN
IF (vsp#NIL) AND (fh.file#NIL) THEN
WriteBytes(fh,vsp,SIZE(VSprite),li);
WITH vsp^ DO
IF vsBob#NIL THEN
WriteBytes(fh,vsBob,SIZE(Bob),li);
END;
IF imageData#NIL THEN
WriteBytes(fh,imageData,width*2*height*depth,li);
END;
IF collMask#NIL THEN
WriteBytes(fh,collMask,width*2*height,li);
END;
IF borderLine#NIL THEN
WriteBytes(fh,borderLine,width*2,li);
END;
END;
END;
END SaveVSprite;
PROCEDURE LoadVSprite(VAR fh : File;
rp : RastPortPtr) : VSpritePtr;
VAR li : LONGINT;
vsp : VSpritePtr;
get : ADDRESS;
BEGIN
IF fh.file#NIL THEN
vsp:=NewAllocRemember(rememberVSprite,SIZE(VSprite),FALSE);
IF vsp#NIL THEN
ReadBytes(fh,vsp,SIZE(VSprite),li);
IF vsp^.vsBob#NIL THEN
vsp^.vsBob:=NewAllocRemember(rememberData,SIZE(Bob),FALSE);
IF vsp^.vsBob#NIL THEN
ReadBytes(fh,vsp^.vsBob,SIZE(Bob),li);
WITH vsp^.vsBob^ DO
IF saveBuffer#NIL THEN
saveBuffer:=NewAllocRemember(rememberData,
vsp^.width*2*vsp^.height*(vsp^.depth+1),TRUE);
IF saveBuffer#NIL THEN
IF dBuffer#NIL THEN
get:=dBuffer^.bufBuffer;
dBuffer:=NewAllocRemember(rememberData,SIZE(DBufPacket),
FALSE);
IF dBuffer#NIL THEN
IF get#NIL THEN
dBuffer^.bufBuffer:=NewAllocRemember(rememberData,
vsp^.width*2*vsp^.height*(vsp^.depth+1),TRUE);
IF dBuffer^.bufBuffer=NIL THEN
DeallocateGel(vsp);
END;
END;
ELSE
DeallocateGel(vsp);
END;
END;
ELSE
DeallocateGel(vsp);
END;
END;
END;
ELSE
DeallocateGel(vsp);
END;
END;
IF vsp#NIL THEN
IF vsp^.imageData#NIL THEN
vsp^.imageData:=NewAllocRemember(rememberData,
vsp^.width*2*vsp^.height*vsp^.depth,TRUE);
IF vsp^.imageData#NIL THEN
ReadBytes(fh,vsp^.imageData,vsp^.width*2*vsp^.height*vsp^.depth,li);
ELSE
DeallocateGel(vsp);
END;
END;
END;
IF vsp#NIL THEN
IF vsp^.collMask#NIL THEN
vsp^.collMask:=NewAllocRemember(rememberData,
vsp^.width*2*vsp^.height,TRUE);
IF vsp^.collMask#NIL THEN
ReadBytes(fh,vsp^.collMask,vsp^.width*2*vsp^.height,li);
ELSE
DeallocateGel(vsp);
END;
END;
END;
IF vsp#NIL THEN
IF vsp^.borderLine#NIL THEN
vsp^.borderLine:=NewAllocRemember(rememberData,vsp^.width*2,TRUE);
IF vsp^.borderLine#NIL THEN
ReadBytes(fh,vsp^.borderLine,vsp^.width*2,li);
ELSE
DeallocateGel(vsp);
END;
END;
END;
IF vsp#NIL THEN
IF vsprite IN vsp^.flags THEN
AddVSprite(vsp,rp);
ELSE
AddBob(vsp^.vsBob,rp);
END;
END;
END;
END;
RETURN vsp;
END LoadVSprite;
PROCEDURE SaveBob(VAR fh : File;
bob : BobPtr);
BEGIN
IF bob#NIL THEN
SaveVSprite(fh,bob^.bobVSprite);
END;
END SaveBob;
PROCEDURE LoadBob(VAR fh : File;
rp : RastPortPtr) : BobPtr;
VAR vsp : VSpritePtr;
BEGIN
vsp:=LoadVSprite(fh,rp);
RETURN vsp^.vsBob;
END LoadBob;
PROCEDURE FreeGel(VAR vsp : VSpritePtr;
rp : RastPortPtr;
vp : ViewPortPtr;
view : ViewPtr;
erase : BOOLEAN);
VAR bl,cm : ADDRESS;
w,h,d : INTEGER;
nb : NewBobPtr;
BEGIN
IF vsp#NIL THEN
IF vsprite IN vsp^.flags THEN
RemVSprite(vsp);
ELSE
IF vsp^.vsBob#NIL THEN
nb:=ADDRESS(vsp^.vsBob);
IF nb^.user=bobAdded THEN
IF (rp#NIL) AND (vp#NIL) THEN
RemIBob(vsp^.vsBob,rp,vp);
ELSE
RemBob(vsp^.vsBob);
END;
END;
END;
END;
IF erase THEN
RedrawGels(rp,vp,view,waitBOVP); (* Sorry *)
END;
DeallocateGel(vsp);
END;
vsp:=NIL;
END FreeGel;
PROCEDURE SetVSpriteImage(vs : VSpritePtr;
buffer : ADDRESS;
owrite : BOOLEAN);
VAR copys,copyd : POINTER TO CARDINAL;
t : INTEGER;
BEGIN
IF (vs#NIL) AND (buffer#NIL) THEN
IF owrite THEN
copys:=buffer; copyd:=vs^.imageData;
IF copyd#NIL THEN
FOR t:=0 TO vs^.width*vs^.height*vs^.depth-1 DO
copyd^:=copys^;
INC(copyd,2); INC(copys,2);
END;
InitMasks(vs);
END;
ELSE
vs^.imageData:=buffer;
InitMasks(vs);
END;
END;
END SetVSpriteImage;
PROCEDURE SetBobImage(bob : BobPtr;
buffer : ADDRESS;
owrite : BOOLEAN);
BEGIN
IF bob#NIL THEN
IF bob^.bobVSprite#NIL THEN
SetVSpriteImage(bob^.bobVSprite,buffer,owrite);
END;
END;
END SetBobImage;
PROCEDURE GetVSpriteImage(vs : VSpritePtr) : ADDRESS;
VAR r : ADDRESS;
BEGIN
r:=NIL;
IF vs#NIL THEN
r:=vs^.imageData;
END;
RETURN r;
END GetVSpriteImage;
PROCEDURE GetBobImage(bob : BobPtr) : ADDRESS;
VAR r : ADDRESS;
BEGIN
r:=NIL;
IF bob#NIL THEN
IF bob^.bobVSprite#NIL THEN
r:=bob^.bobVSprite^.imageData;
END;
END;
RETURN r;
END GetBobImage;
PROCEDURE GetGel(rp : RastPortPtr;
x,y : INTEGER;
w,h : INTEGER;
d : INTEGER;
fl : VSpriteFlagSet;
bfl : BobFlagSet;
hit : BITSET;
me : BITSET;
colors : ADDRESS;
drp : RastPortPtr;
dx,dy : INTEGER;
doub : BOOLEAN;
anim : BOOLEAN;
image : BOOLEAN;
buffer : BobPtr) : VSpritePtr;
VAR vsp : VSpritePtr;
bob : BobPtr;
nb : NewBobPtr;
bitmap : BitMap;
lc : LONGCARD;
BEGIN
vsp:=NewAllocRemember(rememberVSprite,SIZE(VSprite),FALSE);
IF vsp#NIL THEN
WITH vsp^ DO
flags:=fl; x:=dx; y:=dy; width:=(w+15) DIV 16; height:=h; depth:=d;
meMask:=me; hitMask:=hit; sprColors:=colors; planePick:=255;
planeOnOff:=0;
borderLine:=NewAllocRemember(rememberData,width*2,TRUE);
END;
IF vsp^.borderLine#NIL THEN
vsp^.collMask:=NewAllocRemember(rememberData,vsp^.width*2*h,TRUE);
IF vsp^.collMask#NIL THEN
IF vsprite IN fl THEN d:=2; END;
IF image THEN
vsp^.imageData:=NewAllocRemember(rememberData,vsp^.width*2*h*d,TRUE);
END;
IF (vsp^.imageData#NIL) OR NOT image THEN
IF (rp#NIL) AND image THEN
IF vsprite IN fl THEN
WITH bitmap DO
bytesPerRow:=4; rows:=h;
depth:=d; flags:=0;
planes[0]:=vsp^.imageData;
planes[1]:=vsp^.imageData; INC(planes[1],2);
END;
lc:=BltBitMap(rp^.bitMap,x,y,ADR(bitmap),0,0,16,h,192,255,NIL);
ELSE
WITH bitmap DO
bytesPerRow:=vsp^.width*2; rows:=h;
depth:=d; flags:=0;
FOR lc:=0 TO d-1 DO
planes[lc]:=vsp^.imageData+ADDRESS(lc)*vsp^.width*2*h;
END;
END;
lc:=BltBitMap(rp^.bitMap,x,y,ADR(bitmap),0,0,w,h,192,255,NIL);
END;
END;
IF image THEN InitMasks(vsp); END;
IF NOT (vsprite IN fl) THEN
bob:=NewAllocRemember(rememberData,SIZE(Bob)+4,FALSE);
IF bob#NIL THEN
nb:=ADDRESS(bob);
nb^.user:=notAdded;
WITH bob^ DO
bobVSprite:=vsp; flags:=bfl;
vsp^.vsBob:=bob; imageShadow:=vsp^.collMask;
IF buffer=NIL THEN
saveBuffer:=NewAllocRemember(rememberData,vsp^.width*2*h*(d+1),
TRUE);
IF (saveBuffer#NIL) THEN
IF doub THEN
dBuffer:=NewAllocRemember(rememberData,SIZE(DBufPacket),
FALSE);
IF dBuffer#NIL THEN
dBuffer^.bufBuffer:=NewAllocRemember(rememberData,
vsp^.width*2*h*(d+1),TRUE);
IF dBuffer^.bufBuffer=NIL THEN
DeallocateGel(vsp);
END;
ELSE
DeallocateGel(vsp);
END;
END;
ELSE
DeallocateGel(vsp);
END;
ELSE
saveBuffer:=buffer^.saveBuffer;
IF (buffer^.dBuffer#NIL) AND doub THEN
dBuffer:=NewAllocRemember(rememberData,SIZE(DBufPacket),
FALSE);
IF dBuffer#NIL THEN
dBuffer^.bufBuffer:=buffer^.dBuffer^.bufBuffer;
END;
ELSE
dBuffer:=NIL;
END;
END;
END;
ELSE
DeallocateGel(vsp);
END;
END;
IF vsprite IN fl THEN
AddVSprite(vsp,drp);
ELSE
IF NOT anim THEN
AddBob(bob,drp);
IF nb#NIL THEN
nb^.user:=bobAdded;
END;
END;
END;
ELSE
DeallocateGel(vsp);
END;
ELSE
DeallocateGel(vsp);
END;
ELSE
DeallocateGel(vsp);
END;
END;
RETURN vsp;
END GetGel;
PROCEDURE GetVSprite(rp : RastPortPtr;
x,y : INTEGER;
h : INTEGER;
must : BOOLEAN;
image : BOOLEAN;
hit : BITSET;
me : BITSET;
colors : ADDRESS;
drp : RastPortPtr;
dx,dy : INTEGER) : VSpritePtr;
VAR fl : VSpriteFlagSet;
BEGIN
fl:=VSpriteFlagSet{vsprite};
IF must THEN INCL(fl,mustDraw); END;
RETURN GetGel(rp,x,y,16,h,2,fl,BobFlagSet{},hit,me,colors,drp,dx,dy,FALSE,FALSE,image,NIL);
END GetVSprite;
PROCEDURE FreeVSprite(VAR vsp : VSpritePtr;
rp : RastPortPtr;
vp : ViewPortPtr;
view : ViewPtr;
erase : BOOLEAN);
BEGIN
FreeGel(vsp,rp,vp,view,erase);
END FreeVSprite;
PROCEDURE GetBob(rp : RastPortPtr;
x,y : INTEGER;
w,h : INTEGER;
d : INTEGER;
flags : BobTypeFlagSet;
hit : BITSET;
me : BITSET;
buffer : BobPtr;
drp : RastPortPtr;
dx,dy : INTEGER) : BobPtr;
VAR vsp : VSpritePtr;
fl : VSpriteFlagSet;
bfl : BobFlagSet;
BEGIN
fl:=VSpriteFlagSet{};
bfl:=BobFlagSet{};
IF saveBackground IN flags THEN
INCL(fl,saveBack);
END;
IF transparent IN flags THEN
INCL(fl,overlay);
END;
vsp:=GetGel(rp,x,y,w,h,d,fl,bfl,hit,me,NIL,drp,dx,dy,
(doubleBuffering IN flags),(animBob IN flags),NOT (noImage IN flags),
buffer);
IF vsp#NIL THEN
RETURN vsp^.vsBob;
ELSE
RETURN NIL;
END;
END GetBob;
PROCEDURE FreeBob(VAR bob : BobPtr;
rp : RastPortPtr;
vp : ViewPortPtr;
view : ViewPtr;
erase : BOOLEAN);
BEGIN
IF bob#NIL THEN
FreeGel(bob^.bobVSprite,rp,vp,view,erase);
END;
bob:=NIL;
END FreeBob;
PROCEDURE ChangeBitMap(rp : RastPortPtr;
vp : ViewPortPtr;
bitmap : BitMapPtr) : BitMapPtr;
VAR old : BitMapPtr;
BEGIN
old:=bitmap;
IF (rp#NIL) AND (vp#NIL) AND (bitmap#NIL) THEN
old:=vp^.rasInfo^.bitMap;
IF old=NIL THEN
old:=rp^.bitMap;
END;
vp^.rasInfo^.bitMap:=bitmap;
rp^.bitMap:=bitmap;
END;
RETURN old;
END ChangeBitMap;
VAR rememberGelsInfo : NewRememberPtr;
PROCEDURE GetGelsInfo(rp : RastPortPtr;
spr : SHORTSET;
minX,maxX : INTEGER;
minY,maxY : INTEGER) : AllGelsInfoPtr;
VAR gals : AllGelsInfoPtr;
gels : GelsInfoPtr;
va,vb : VSpritePtr;
tt : POINTER TO SHORTINT;
BEGIN
gals:=NewAllocRemember(rememberGelsInfo,SIZE(AllGelsInfo),FALSE);
IF gals#NIL THEN
gels:=ADR(gals^.gelsInfo);
IF gels#NIL THEN
WITH gels^ DO
leftmost:=minX; rightmost:=maxX;
topmost:=minY; bottommost:=maxY;
tt:=ADR(spr); sprRsrvd:=tt^;
gelHead:=NewAllocRemember(rememberData,SIZE(VSprite),FALSE);
END;
IF gels^.gelHead#NIL THEN
gels^.gelTail:=NewAllocRemember(rememberData,SIZE(VSprite),FALSE);
IF gels^.gelTail#NIL THEN
gels^.nextLine:=NewAllocRemember(rememberData,16,FALSE);
IF gels^.nextLine#NIL THEN
gels^.lastColor:=NewAllocRemember(rememberData,32,FALSE);
IF gels^.lastColor#NIL THEN
gels^.collHandler:=NewAllocRemember(rememberData,SIZE(CollTable),FALSE);
IF gels^.collHandler#NIL THEN
va:=gels^.gelHead; vb:=gels^.gelTail;
InitGels(va,vb,gels);
rp^.gelsInfo:=gels;
ELSE
FreeGelsInfo(gals);
END;
ELSE
FreeGelsInfo(gals);
END;
ELSE
FreeGelsInfo(gals);
END;
ELSE
FreeGelsInfo(gals);
END;
ELSE
FreeGelsInfo(gals);
END;
END;
END;
RETURN gals;
END GetGelsInfo;
PROCEDURE SetGelsInfo(rp : RastPortPtr;
allGelsInfo : AllGelsInfoPtr);
BEGIN
IF rp#NIL THEN
rp^.gelsInfo:=ADR(allGelsInfo^.gelsInfo);
END;
END SetGelsInfo;
PROCEDURE FreeGelsInfo(VAR allGelsInfo : AllGelsInfoPtr);
VAR gelsinfo : GelsInfoPtr;
BEGIN
IF allGelsInfo#NIL THEN
gelsinfo:=ADR(allGelsInfo^.gelsInfo);
WITH gelsinfo^ DO
CutRememberStructure(rememberData,collHandler,TRUE);
CutRememberStructure(rememberData,lastColor,TRUE);
CutRememberStructure(rememberData,nextLine,TRUE);
CutRememberStructure(rememberData,gelTail,TRUE);
CutRememberStructure(rememberData,gelHead,TRUE);
END;
CutRememberStructure(rememberGelsInfo,allGelsInfo,TRUE);
END;
allGelsInfo:=NIL;
END FreeGelsInfo;
VAR agi : AllGelsInfoPtr;
(*$ EntryExitCode:=FALSE *)
PROCEDURE BorderHandler(coll{0} : CollisionBorderSet;
vsprite{11} : VSpritePtr);
BEGIN
ASSEMBLE(RELOCATION
MOVEM.L D0-D7/A0-A6,-(SP)
MOVEM.L D0-D1/A0-A1,-(SP)
MOVE.L #0,A1
MOVE.L 4,A6
JSR FindTask(A6)
MOVE.L D0,A0
MOVE.L Task.userData(A0),A4
MOVEM.L (SP)+,D0-D1/A0-A1
END);
agi^.borderProc(vsprite,coll);
ASSEMBLE(MOVEM.L (SP)+,D0-D7/A0-A6
RTS
END);
END BorderHandler;
PROCEDURE SetBorderCollisionProcedure(proc : BorderCollProc;
allGelsInfo : AllGelsInfoPtr);
BEGIN
IF allGelsInfo#NIL THEN
allGelsInfo^.borderProc:=proc;
SetCollision(0,CAST(PROC,ADR(BorderHandler)),ADR(allGelsInfo^.gelsInfo));
END;
END SetBorderCollisionProcedure;
(*$ EntryExitCode:=FALSE *)
PROCEDURE GelsHandler(vsprb{10} : VSpritePtr;
vspra{2} : VSpritePtr);
VAR nr{1} : INTEGER;
BEGIN
ASSEMBLE(RELOCATION
MOVEM.L D0-D7/A0-A6,-(SP)
LEA l2,A0
MOVEQ #1,D1
JMP jump(PC)
l2: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l3,A0
MOVEQ #2,D1
JMP jump(PC)
l3: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l4,A0
MOVEQ #3,D1
JMP jump(PC)
l4: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l5,A0
MOVEQ #4,D1
JMP jump(PC)
l5: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l6,A0
MOVEQ #5,D1
JMP jump(PC)
l6: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l7,A0
MOVEQ #6,D1
JMP jump(PC)
l7: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l8,A0
MOVEQ #7,D1
JMP jump(PC)
l8: MOVEM.L D0-D7/A0-A6,-(SP)
LEA l9,A0
MOVEQ #8,D1
JMP jump(PC)
l9: MOVEM.L D0-D7/A0-A6,-(SP)
LEA la,A0
MOVEQ #9,D1
JMP jump(PC)
la: MOVEM.L D0-D7/A0-A6,-(SP)
LEA lb,A0
MOVEQ #10,D1
JMP jump(PC)
lb: MOVEM.L D0-D7/A0-A6,-(SP)
LEA lc,A0
MOVEQ #11,D1
JMP jump(PC)
lc: MOVEM.L D0-D7/A0-A6,-(SP)
LEA ld,A0
MOVEQ #12,D1
JMP jump(PC)
ld: MOVEM.L D0-D7/A0-A6,-(SP)
LEA le,A0
MOVEQ #13,D1
JMP jump(PC)
le: MOVEM.L D0-D7/A0-A6,-(SP)
LEA lf,A0
MOVEQ #14,D1
JMP jump(PC)
lf: MOVEM.L D0-D7/A0-A6,-(SP)
MOVEQ #15,D1
jump:
MOVEM.L D0-D1/A0-A1,-(SP)
MOVE.L #0,A1
MOVE.L 4,A6
JSR FindTask(A6)
MOVE.L D0,A0
MOVE.L Task.userData(A0),A4
MOVEM.L (SP)+,D0-D1/A0-A1
END);
agi^.gelsProc[nr](vspra,vsprb);
ASSEMBLE(MOVEM.L (SP)+,D0-D7/A0-A6
RTS
END);
END GelsHandler;
PROCEDURE SetGelsCollisionProcedure(num : LONGCARD;
proc : GelsCollProc;
allGelsInfo : AllGelsInfoPtr);
VAR adr : ADDRESS;
BEGIN
IF (num>=1) AND (num<=15) AND (allGelsInfo#NIL) THEN
allGelsInfo^.gelsProc[num]:=proc;
adr:=ADR(GelsHandler); INC(adr,(num-1)*16);
SetCollision(num,CAST(PROC,adr),ADR(allGelsInfo^.gelsInfo));
END;
END SetGelsCollisionProcedure;
PROCEDURE TestCollision(rp : RastPortPtr);
VAR task : TaskPtr;
BEGIN
IF rp#NIL THEN
agi:=ADDRESS(rp^.gelsInfo);
IF agi#NIL THEN
task:=FindTask(NIL);
IF task#NIL THEN task^.userData:=REG(12); END;
DoCollision(rp);
END;
END;
END TestCollision;
VAR rememberAnimation : NewRememberPtr;
rememberComp : NewRememberPtr;
PROCEDURE InitAnim() : AnimPtr;
VAR ao : AnimPtr;
x,y : INTEGER;
BEGIN
ao:=NewAllocRemember(rememberAnimation,SIZE(Anim),FALSE);
IF ao#NIL THEN
WITH ao^.animOb DO
nextOb:=NIL; prevOb:=NIL; clock:=0; anX:=-256*64; anY:=-256*64;
xAccel:=0; yAccel:=0; xVel:=0; yVel:=0; ringXTrans:=0; ringYTrans:=0;
animORoutine:=NIL; headComp:=NIL;
END;
END;
RETURN ao;
END InitAnim;
PROCEDURE AddAnimBob(anim : AnimPtr;
bob : BobPtr;
time : INTEGER;
xt,yt : FFP);
VAR animc : AnimCompPtr;
BEGIN
IF (anim#NIL) AND (bob#NIL) THEN
IF anim^.firstComp#NIL THEN
animc:=anim^.firstComp;
WHILE animc^.nextSeq#NIL DO animc:=animc^.nextSeq; END;
animc^.nextSeq:=NewAllocRemember(rememberComp,SIZE(AnimComp),FALSE);
IF animc^.nextSeq#NIL THEN animc^.nextSeq^.prevSeq:=animc; END;
animc:=animc^.nextSeq;
ELSE
anim^.firstComp:=NewAllocRemember(rememberComp,SIZE(AnimComp),FALSE);
animc:=anim^.firstComp;
END;
IF animc#NIL THEN
WITH animc^ DO
flags:=ringtrigger; prevComp:=NIL; nextComp:=NIL;
timeSet:=time; yTrans:=TRUNC(yt*64.0)+256*64;
xTrans:=TRUNC(xt*64.0)+256*64;
animCRoutine:=NIL; headOb:=ADR(anim^.animOb);
IF bob#NIL THEN
INCL(bob^.flags,bobIsComp); bob^.bobComp:=animc;
END;
animBob:=bob;
END;
END;
END;
END AddAnimBob;
PROCEDURE EndAnimDefinition(VAR list : AnimPtr;
anim : AnimPtr;
rp : RastPortPtr;
proc : AnimProc);
VAR animc : AnimCompPtr;
aanim : AnimPtr;
a1,a2 : AnimObPtr;
b1,b2 : ADDRESS;
nb : NewBobPtr;
BEGIN
IF (anim#NIL) AND (rp#NIL) THEN
IF anim^.firstComp#NIL THEN
animc:=anim^.firstComp;
WHILE animc^.nextSeq#NIL DO
nb:=ADDRESS(animc^.animBob); nb^.user:=bobAdded;
animc:=animc^.nextSeq;
END;
nb:=ADDRESS(animc^.animBob); nb^.user:=bobAdded;
animc^.nextSeq:=anim^.firstComp;
anim^.firstComp^.prevSeq:=animc;
anim^.animOb.headComp:=anim^.firstComp;
anim^.animProc:=proc;
IF list=NIL THEN
a1:=ADR(anim^.animOb); a2:=NIL;
AddAnimOb(a1,a2,rp);
list:=anim;
ELSE
a1:=ADR(anim^.animOb); a2:=ADR(list^.animOb);
AddAnimOb(a1,a2,rp);
aanim:=list;
WHILE aanim^.next#NIL DO
aanim:=aanim^.next;
END;
aanim^.next:=anim;
aanim^.next^.prev:=aanim;
END;
list^.rp:=rp;
END;
END;
END EndAnimDefinition;
PROCEDURE ChangeComp(anim : AnimPtr;
bob : BobPtr;
time : INTEGER;
xt,yt : FFP);
VAR rem : NewRememberPtr;
aanim : AnimPtr;
animc : AnimCompPtr;
BEGIN
IF (anim#NIL) AND (bob#NIL) THEN
rem:=rememberComp;
WHILE rem#NIL DO
aanim:=GetAddress(rem);
animc:=anim^.firstComp;
WHILE animc#NIL DO
IF animc^.animBob=bob THEN
animc^.timeSet:=time; animc^.yTrans:=TRUNC(yt*64.0)+256*64;
animc^.xTrans:=TRUNC(xt*64.0)+256*64;
END;
animc:=animc^.nextSeq;
END;
rem:=rem^.next;
END;
END;
END ChangeComp;
PROCEDURE SetAnim(anim : AnimPtr;
px,py : FFP;
vx,vy : FFP;
ax,ay : FFP);
VAR x,y : INTEGER;
BEGIN
IF anim#NIL THEN
WITH anim^.animOb DO
anX:=TRUNC(px*64.0)-256*64; anY:=TRUNC(py*64.0)-256*64;
xVel:=TRUNC(vx*64.0); xAccel:=TRUNC(ax*64.0);
yVel:=TRUNC(vy*64.0); yAccel:=TRUNC(ay*64.0);
END;
END;
END SetAnim;
PROCEDURE GetActualVelocity(anim : AnimPtr;
VAR vx,vy : FFP);
BEGIN
IF anim#NIL THEN
vx:=FFP(anim^.animOb.xVel)/64.0;
vy:=FFP(anim^.animOb.yVel)/64.0;
END;
END GetActualVelocity;
PROCEDURE GetActualPosition(anim : AnimPtr;
VAR px,py : FFP);
BEGIN
IF anim#NIL THEN
px:=FFP(anim^.animOb.anX)/64.0+256.0;
py:=FFP(anim^.animOb.anY)/64.0+256.0;
END;
END GetActualPosition;
PROCEDURE AnimObjects(list : AnimPtr);
VAR anim : AnimPtr;
animc : AnimObPtr;
BEGIN
IF list#NIL THEN
anim:=list;
WHILE anim#NIL DO
IF anim^.animProc#NIL THEN anim^.animProc(anim); END;
anim:=anim^.next;
END;
animc:=ADR(list^.animOb);
Animate(animc,list^.rp);
END;
END AnimObjects;
PROCEDURE FreeAnim(VAR anim : AnimPtr);
VAR animc,next : AnimCompPtr;
BEGIN
IF anim#NIL THEN
WITH anim^.animOb DO
IF prevOb#NIL THEN prevOb^.nextOb:=nextOb; END;
IF nextOb#NIL THEN nextOb^.prevOb:=prevOb; END;
END;
animc:=anim^.firstComp;
IF animc#NIL THEN
REPEAT
next:=animc^.nextSeq;
CutRememberStructure(rememberComp,animc,TRUE);
animc:=next;
UNTIL (animc=NIL) OR (animc=anim^.firstComp);
END;
CutRememberStructure(rememberAnimation,anim,TRUE);
END;
anim:=NIL;
END FreeAnim;
CONST WC = 180.0/3.1415926536;
VAR rememberTurtle : NewRememberPtr;
PROCEDURE InitTurtleGraphics(rp : RastPortPtr) : TurtleHandlePtr;
VAR t : TurtleHandlePtr;
BEGIN
IF rp#NIL THEN
t:=NewAllocRemember(rememberTurtle,SIZE(TurtleHandle),FALSE);
IF t#NIL THEN
t^.rp:=rp;
WITH t^ DO
x:=FFP(4*rp^.bitMap^.bytesPerRow);
y:=FFP(rp^.bitMap^.rows/2);
actAngle:=0; penUp:=FALSE; cursorOn:=TRUE;
END;
DrawCursor(t);
END;
END;
RETURN t;
END InitTurtleGraphics;
PROCEDURE SetTurtleRast(t : TurtleHandlePtr;
c : INTEGER);
BEGIN
IF t#NIL THEN
WITH t^ DO
IF rp#NIL THEN
SetRast(rp,c);
END;
IF cursorOn THEN
DrawCursor(t);
END;
END;
END;
END SetTurtleRast;
PROCEDURE DrawCursor(t : TurtleHandlePtr);
VAR d : DrawModeSet;
w : FFP;
mx1,mx2,mx3,mx4,my1,my2,my3,my4 : INTEGER;
BEGIN
IF t#NIL THEN
WITH t^ DO
d:=rp^.drawMode;
SetDrMd(rp,DrawModeSet{complement});
mx4:=TRUNC(x); my4:=TRUNC(y);
w:=FFP(actAngle)/WC;
mx1:=TRUNC(x-10.0*Sin(w));
my1:=TRUNC(y-10.0*Cos(w));
w:=FFP(actAngle+120)/WC;
mx2:=TRUNC(x-8.0*Sin(w));
my2:=TRUNC(y-8.0*Cos(w));
w:=FFP(actAngle-120)/WC;
mx3:=TRUNC(x-8.0*Sin(w));
my3:=TRUNC(y-8.0*Cos(w));
Move(rp,mx4,my4);
Draw(rp,mx3,my3);
Draw(rp,mx1,my1);
Draw(rp,mx2,my2);
Draw(rp,mx4,my4);
SetDrMd(rp,d);
END;
END;
END DrawCursor;
PROCEDURE Forward(t : TurtleHandlePtr;
m : INTEGER);
VAR w,f : FFP;
xi,yi : INTEGER;
BEGIN
IF t#NIL THEN
WITH t^ DO
xi:=TRUNC(x); yi:=TRUNC(y);
Move(rp,xi,yi);
IF cursorOn THEN DrawCursor(t); END;
f:=FFP(m);
w:=FFP(actAngle)/WC;
x:=x-f*Sin(w);
y:=y-f*Cos(w);
IF NOT penUp THEN
xi:=TRUNC(x); yi:=TRUNC(y);
Draw(rp,xi,yi);
END;
IF cursorOn THEN DrawCursor(t); END;
END;
END;
END Forward;
PROCEDURE Backward(t : TurtleHandlePtr;
m : INTEGER);
BEGIN
Forward(t,-m);
END Backward;
PROCEDURE Right(t : TurtleHandlePtr;
w : INTEGER);
BEGIN
IF t#NIL THEN
WITH t^ DO
IF cursorOn THEN DrawCursor(t); END;
actAngle:=(actAngle+360+w) MOD 360;
IF cursorOn THEN DrawCursor(t); END;
END;
END;
END Right;
PROCEDURE Left(t : TurtleHandlePtr;
w : INTEGER);
BEGIN
Right(t,-w);
END Left;
PROCEDURE Home(t : TurtleHandlePtr);
BEGIN
IF t#NIL THEN
WITH t^ DO
IF cursorOn THEN DrawCursor(t); END;
x:=FFP(4*rp^.bitMap^.bytesPerRow);
y:=FFP(rp^.bitMap^.rows/2);
actAngle:=0;
IF cursorOn THEN DrawCursor(t); END;
END;
END;
END Home;
PROCEDURE PenUp(t : TurtleHandlePtr);
BEGIN
IF t#NIL THEN
t^.penUp:=TRUE;
END;
END PenUp;
PROCEDURE PenDown(t : TurtleHandlePtr);
BEGIN
IF t#NIL THEN
t^.penUp:=FALSE;
END;
END PenDown;
PROCEDURE TurtleCursor(t : TurtleHandlePtr;
on : BOOLEAN);
BEGIN
IF t#NIL THEN
IF on#t^.cursorOn THEN
DrawCursor(t);
t^.cursorOn:=on;
END;
END;
END TurtleCursor;
PROCEDURE FreeTurtleGraphics(VAR t : TurtleHandlePtr);
BEGIN
IF t#NIL THEN
WITH t^ DO
IF cursorOn THEN DrawCursor(t); END;
END;
CutRememberStructure(rememberTurtle,t,TRUE);
END;
t:=NIL;
END FreeTurtleGraphics;
VAR rem : NewRememberPtr;
vs : VSpritePtr;
rt : RasterPtr;
sp : SpriteHandlePtr;
bm : BitMapPtr;
vw : ViewHandlePtr;
gi : AllGelsInfoPtr;
ai : SAreaHandlePtr;
an : AnimPtr;
BEGIN
gfxBase:=ADR(GraphicsL);
CLOSE
rem:=rememberSprite;
WHILE rem#NIL DO
sp:=GetAddress(rem);
RemSprite(sp);
rem:=rem^.next;
END;
NewFreeRemember(rememberSprite,TRUE);
rem:=rememberVSprite;
WHILE rem#NIL DO
vs:=GetAddress(rem);
FreeGel(vs,NIL,NIL,NIL,FALSE);
rem:=rem^.next;
END;
NewFreeRemember(rememberVSprite,TRUE);
rem:=rememberAnimation;
WHILE rem#NIL DO
an:=GetAddress(rem);
FreeAnim(an);
rem:=rem^.next;
END;
NewFreeRemember(rememberAnimation,TRUE);
rem:=rememberGelsInfo;
WHILE rem#NIL DO
gi:=GetAddress(rem);
FreeGelsInfo(gi);
rem:=rem^.next;
END;
NewFreeRemember(rememberGelsInfo,TRUE);
rem:=rememberView;
WHILE rem#NIL DO
vw:=GetAddress(rem);
FreeView(vw);
rem:=rem^.next;
END;
NewFreeRemember(rememberView,TRUE);
rem:=rememberRaster;
WHILE rem#NIL DO
rt:=GetAddress(rem);
FreeTmpRas(rt);
rem:=rem^.next;
END;
NewFreeRemember(rememberRaster,TRUE);
rem:=rememberBitmap;
WHILE rem#NIL DO
bm:=GetAddress(rem);
FreeBitMap(bm);
rem:=rem^.next;
END;
NewFreeRemember(rememberBitmap,TRUE);
NewFreeRemember(rememberData,TRUE);
NewFreeRemember(rememberComp,TRUE);
NewFreeRemember(rememberTurtle,TRUE);
END GraphicsSupport.